//-----------------------------------------------------------------------------
//	file: spi_module.v
//		spi模块，只能作为master，支持8/16bit，支持cpol和cpha
//-----------------------------------------------------------------------------
module spi_module #(
	// parameter config
	parameter	DATA_WIDTH		= 8,
	parameter	CONFIG_CPOL		= 1'b0,
	parameter	CONFIG_CPHA		= 1'b0,
	// parameter div
	parameter	DIV_CNT_WIDTH	= 2,
	parameter	DIV_CNT_HALF	= 2'd1,
	parameter	DIV_CNT_CYCLE	= 2'd3,
	// parameter wait
	parameter	WAIT_CNT_WIDTH	= 2,
	parameter	WAIT_CNT_CYCLE	= 2'd3
)
(
	input		clk,
	input		reset,
	// control
	input		enable,
	// flag
	output		rd_mem_en,
	output		wr_mem_en,
	// data
	input		[DATA_WIDTH-1:0] pout,
	output		[DATA_WIDTH-1:0] pin,
	// interface
	output		nss,
	output		sck,
	input		miso,
	output		mosi
);

// wire
wire	load;
wire	pick;
wire	stop;
wire	working;
wire	shif_en;
wire	samp_en;

// link
assign	rd_mem_en = pick;
assign	wr_mem_en = pick;

// spi fsm
spi_fsm #(
	.WAIT_CNT_WIDTH	(WAIT_CNT_WIDTH),
	.WAIT_CNT_CYCLE	(WAIT_CNT_CYCLE)
)
spi_fsm_inst (
	.clk		(clk),
	.reset		(reset),
	.enable		(enable),
	.stop		(stop),
	.working	(working),
	.load		(load),
	.pick		(pick),
	.nss		(nss)
);

// spi clock
spi_clk #(
	.DATA_WIDTH		(DATA_WIDTH),
	.DIV_CNT_WIDTH	(DIV_CNT_WIDTH),
	.DIV_CNT_HALF	(DIV_CNT_HALF),
	.DIV_CNT_CYCLE	(DIV_CNT_CYCLE)
)
spi_clk_inst (
	.clk		(clk),
	.reset		(reset),
	.cpol		(CONFIG_CPOL),
	.cpha		(CONFIG_CPHA),
	.working	(working),
	.sck		(sck),
	.stop		(stop),
	.shif_en	(shif_en),
	.samp_en	(samp_en)
);

// spi sin
spi_sin #(
	.DATA_WIDTH	(DATA_WIDTH)
)
spi_sin_inst (
	.clk		(clk),
	.reset		(reset),
	.samp_en	(samp_en),
	.miso		(miso),
	.pin		(pin)
);

// spi sout
spi_sout #(
	.DATA_WIDTH	(DATA_WIDTH)
)
spi_sout_inst (
	.clk		(clk),
	.reset		(reset),
	.load		(load),
	.shif_en	(shif_en),
	.mosi		(mosi),
	.pout		(pout)
);

endmodule
